﻿using AwesomiumDotNet;
using SampleFramework;
using System;
using System.Drawing;
using SlimDX;
using SlimDX.Direct3D9;
using SlimDX.DirectInput;

namespace SlimDXSample
{
    class SlimDXSample : Game
    {
        int Width = 1024, Height = 768;
        Color ClearColor = Color.FromArgb(15, 56, 102);
        string URL = "http://www.google.com";

        Input input;
        UIManager ui;
        UIForm window1;
        UIInfoForm info;
        Fader fader;

        Mesh box;
        Light light;
        Material material;

        float rotAngle = 0.3f;

        // Shortcut to device
        public SlimDX.Direct3D9.Device Device
        {
            get { return GraphicsDeviceManager.Direct3D9.Device; }
        }

        public SlimDXSample()
        {
            Window.ClientSize = new Size(Width, Height);
            Window.Text = "AwesomiumDotNet sample - SlimDX";

            DeviceSettings ds = new DeviceSettings();
            ds.DeviceVersion = DeviceVersion.Direct3D9;
            ds.Windowed = true;
            ds.EnableVSync = false;
            ds.DeviceType = SlimDX.Direct3D9.DeviceType.Hardware;
            ds.BackBufferWidth = Width;
            ds.BackBufferHeight = Height;
            ds.BackBufferCount = 0;
            ds.MultisampleType = MultisampleType.TwoSamples;
            GraphicsDeviceManager.ChangeDevice(ds);
            IsFixedTimeStep = false;
        }

        protected override void OnExiting(EventArgs e)
        {
            base.OnExiting(e);
            Dispose();
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            if (input != null) input.Dispose();
            if (box != null) box.Dispose();
            if (fader != null) fader.Dispose();
        }

        protected override void Initialize()
        {
            base.Initialize();
            input = new Input(Window);
            fader = new Fader(Device);

            ui = new UIManager(Device, Window);
            Resources.Add(ui);

            window1 = new UIForm(ui, 640, 512, UIFlags.Center);
            window1.LoadUrl(URL);
            info = new UIInfoForm(ui);
            
            box = Mesh.CreateBox(Device, 1.0f, 1.0f, 1.0f);
            box.ComputeNormals();

            light = new Light();
            light.Type = LightType.Directional;
            light.Direction = new Vector3(-1, -2, 1);
            light.Diffuse = Color.LemonChiffon;

            material = new Material();
            material.Diffuse = Color.Gray;
            material.Ambient = Color.LawnGreen;
        }

        protected override void LoadContent()
        {
            base.LoadContent();
            input.OnResetDevice();

            Device.Material = material;
            Device.SetLight(0, light);
            Device.EnableLight(0, true);
            Device.SetRenderState(RenderState.Ambient, new Color4(0.5f, 0.5f, 0.5f).ToArgb());

            Device.SetRenderState(RenderState.AlphaBlendEnable, true);
            Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
            Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
        }

        protected override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            // Get events
            input.GetCurrentState();

            // Handle mouse events
            if (input.MousePoint != Point.Empty)
                ui.MouseEvent(input);

            // Handle keyboard events
            if (input.KeyboardState != null)
            {
                // Exit
                if (input.KeyboardState.IsPressed(Key.Escape))
                {
                    Exit();
                    return;
                }

                // Toggle fullscreen
                if (input.keyboardDown.Contains(Key.F11))
                    GraphicsDeviceManager.ToggleFullScreen();

                // Toggle transparency
                if (input.keyboardDown.Contains(Key.F2))
                    window1.IsTransparent = false;

                if (input.keyboardDown.Contains(Key.F3))
                    window1.IsTransparent = true;

                if (ui.KeyboardEvent(input) == false)
                {
                    // Handle keys that weren't handled by any webviews
                }
            }
            
            info.SetText(
                "Esc - Exit</br>" +
                "F11 - Toggle Fullscreen</br>" +
                "<br>" +
                "Transparent Background:</br>" +
                "F2 - Remove</br>" +
                "F3 - Set</br>" +
                "</br>" +
                "FPS: " + gameTime.FramesPerSecond
            );
        }

        protected override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);

            Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, ClearColor, 1.0f, 0);
            Device.BeginScene();

            rotAngle += gameTime.ElapsedRealTime * 0.1f;
            Vector3 cameraPos = new Vector3((float)Math.Sin(rotAngle) * 10, 5, (float)Math.Cos(rotAngle) * 10);

            // Render 3d scene
            
            Matrix Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, (float)Width / (float)Height, 0.1f, 40.0f);
            Matrix View = Matrix.LookAtLH(cameraPos, new Vector3(rotAngle, 0, 10), Vector3.UnitY);
            Device.SetTransform(TransformState.Projection, Projection);
            Device.SetTransform(TransformState.View, View);
            Device.SetTransform(TransformState.World, Matrix.Identity);

            Device.SetRenderState(RenderState.Lighting, true);
            Device.SetRenderState(RenderState.ZEnable, true);

            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    Device.SetTransform(TransformState.World, Matrix.Translation(i*2, 0, j*2));
                    box.DrawSubset(0);
                }
            }

            // Render 2d sprites
            
            Device.SetRenderState(RenderState.Lighting, false);
            Device.SetRenderState(RenderState.ZEnable, false);

            ui.Draw();
            fader.Draw(gameTime);

            Device.EndScene();
        }
    }
}
